package com.framework.admin.service.impl;

import com.framework.admin.repository.SysDeptRepository;
import com.framework.admin.mapper.SysDeptMapper;
import com.framework.admin.model.SysDept;
import com.framework.admin.service.IDeptService;
import com.framework.common.config.SessionUtil;
import com.framework.common.constants.FieldConstant;
import com.framework.common.vo.TreeNode;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class DeptService implements IDeptService {
    @Autowired
    SysDeptRepository sysDeptRepository;
    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Override
    public void save(SysDept sysDept) {
        if (com.framework.common.util.StringUtils.isNotEmpty(sysDept.getId())) {
            sysDeptRepository.updateById(sysDept);
        } else {
            sysDeptRepository.save(sysDept);
        }
    }

    @Override
    public void delete(List<String> ids) {
        String[] arr = new String[ids.size()];
        sysDeptRepository.deleteById(ids.toArray(arr));
    }


    @Override
    public List<SysDept> deptList(SysDept sysDept) {
        List<String> authCodes = new ArrayList<>();
        if (!SessionUtil.isSuperAdmin() && StringUtils.isBlank(sysDept.getPid())) {
            authCodes.addAll(SessionUtil.listDeptCode());
        }
        return sysDeptMapper.findDept(sysDept, authCodes);
    }

    @Override
    public Page<SysDept> deptPage(SysDept dept, Pageable pageable) {
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher(FieldConstant.FULL_NAME, ExampleMatcher.GenericPropertyMatchers.contains());
        Example<SysDept> example = Example.of(dept, matcher);
        return sysDeptRepository.findAll(example, pageable);
    }

    @Override
    public List<TreeNode<SysDept>> deptTree(SysDept sysDept) {
        List<SysDept> list = this.deptList(sysDept);
        List<SysDept> topList = list.stream().filter(o -> FieldConstant.ROOT.equals(o.getPid())).collect(Collectors.toList());
        list.removeAll(topList);
        List<TreeNode<SysDept>> parents = new ArrayList<>();
        setChildren(topList, list, parents);
        return parents;
    }

    private void setChildren(List<SysDept> topList, List<SysDept> allList, List<TreeNode<SysDept>> treeNode) {
        topList.forEach(o -> {
            TreeNode<SysDept> child = new TreeNode<>();
            child.setId(o.getId());
            child.setPid(o.getPid());
            child.setName(o.getSimpleName());
            child.setData(o);
            treeNode.add(child);
            List<SysDept> children = allList.stream().filter(c -> o.getId().equals(c.getPid())).collect(Collectors.toList());
            if (children.size() > 0){
                allList.removeAll(children);
                child.newChildren();
            }
            setChildren(children, allList, child.getChildren());
        });
    }
}
